#ifndef __PCPT_COMM_FORMAT_H__
#define __PCPT_COMM_FORMAT_H__

#include "comm/comm_base.h"
#include "comm_extend/comm_base_extend.h"

using namespace std;

/**************************************************************************************
功能描述: 栅格化
修改记录:
**************************************************************************************/
class PCPT_GRID_C
{
public:
    PCPT_GRID_C(RECTANGLE_STRU &stRectangle, float gridSize)
      : isInit_(false),
        gridSize_(gridSize),
        minX_(stRectangle.minX), minY_(stRectangle.minY),
        maxX_(stRectangle.maxX), maxY_(stRectangle.maxY),
        gridNumX_(0), gridNumY_(0), gridNumXY_(0)
    {}

    ~PCPT_GRID_C(){}

    INT32 Init();
    BOOL  IsInit();
    
    INT32 CalculateGridIndex(const MyPoint &point);
    INT32 CalculateGridIndex(INT32 gridX, INT32 gridY);
    
    BOOL  IsInRectangle(INT32 gridX, INT32 gridY);
    BOOL  IsInRectangle(const MyPoint &point);
    
    INT32 GetGridNumX();
    INT32 GetGridNumY();
    INT32 GetGridNum();
    
    void  GetNeighborGrid(const MyPoint &point, INT32 steps, vector<INT32> &vNeighborIndex);
    void  GetNeighborGrid(INT32 gridX, INT32 gridY, INT32 steps, vector<INT32> &vNeighborIndex);

private:
    BOOL    isInit_;
    float   gridSize_;
    float   minX_, minY_;
    float   maxX_, maxY_;

    INT32   gridNumX_;
    INT32   gridNumY_;
    INT32   gridNumXY_;

    void  CalculateGridCoor(const MyPoint &point, INT32 &gridX, INT32 &gridY);
};

/**************************************************************************************
功能描述: 体素化
修改记录:
**************************************************************************************/
class PCPT_VOXEL_C
{
public:
    PCPT_VOXEL_C(CUBOID_STRU &stCuboid, float voxelSize)
      : isInit_(false),
        voxelSize_(voxelSize),
        minX_(stCuboid.minX), minY_(stCuboid.minY), minZ_(stCuboid.minZ),
        maxX_(stCuboid.maxX), maxY_(stCuboid.maxY), maxZ_(stCuboid.maxZ),
        voxelNumX_(0), voxelNumY_(0), voxelNumZ_(0),
        voxelNumXY_(0), voxelNumXYZ_(0),
        pVoxelArray_(NULL)
    {}

    ~PCPT_VOXEL_C()
    {
        if (pVoxelArray_){
            delete[] pVoxelArray_;
            pVoxelArray_ = NULL;
        }
    }

    INT32 Init();
    BOOL  IsInit();
    
    void  ResetVoxelArray();
    
    INT32 AddPoint2VoxelCellWithCoor(const MyPoint &point, VOXEL_COORDINATE_STRU &stVoxelCoor);
    
    INT32 NeighborVoxelCount(const VOXEL_COORDINATE_STRU &stVoxelCoor, INT32 steps);
    INT32 NeighborVoxelValue(const VOXEL_COORDINATE_STRU &stVoxelCoor, INT32 steps);
    
    BOOL  HasEnoughNeigVoxelCount(const VOXEL_COORDINATE_STRU &stVoxelCoor, INT32 steps, INT32 minNeighbors);
    BOOL  HasEnoughNeigVoxelValue(const VOXEL_COORDINATE_STRU &stVoxelCoor, INT32 steps, INT32 minNeighbors);

    INT32 GetVoxelNumX();
    INT32 GetVoxelNumY();
    INT32 GetVoxelNumZ();
    INT32 GetVoxelNumXY();
    INT32 GetVoxelNum();
    
private:
    BOOL    isInit_;
    
    float   voxelSize_;
    float   minX_, minY_, minZ_;
    float   maxX_, maxY_, maxZ_;
    
    INT32   voxelNumX_, voxelNumY_, voxelNumZ_;
    INT32   voxelNumXY_, voxelNumXYZ_;
    
    UINT08* pVoxelArray_;

    BOOL  IsInVoxelCuboid(const VOXEL_COORDINATE_STRU &stVoxelCoor);
    BOOL  IsInVoxelCuboid(INT32 x, INT32 y, INT32 z);
    BOOL  IsInVoxelCuboid(const MyPoint &point);

    void  CalculateVoxelCoor(const MyPoint &point, VOXEL_COORDINATE_STRU &stVoxelCoor);
    INT32 CalculateVoxelIndex(const VOXEL_COORDINATE_STRU &stVoxelCoor);
    INT32 CalculateVoxelIndex(INT32 x, INT32 y, INT32 z);

    void  Add2VoxelCell(const VOXEL_COORDINATE_STRU &stVoxelCoor);

    void  GetNeighborVoxel(const VOXEL_COORDINATE_STRU &stVoxelCoor, INT32 steps, vector<INT32> &vNeighborIndex);
};

#endif
